﻿using ScannerApp.Common.PLC;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
//BU43
namespace ScannerApp.Common
{
    class DeltaPLC
    {
        private static bool isTCP = false;

        public static bool IsTCP { get => isTCP; set => isTCP = value; }

        public static void SetSerial(string Port, int Baud, int StopBits, int Parity, int DataBits)
        {
            Modbus.COMPort = Port;
            Modbus.Baud = Baud;//9600
            Modbus.StopBits = StopBits;//2
            Modbus.Parity = Parity;//1
            Modbus.DataBits = DataBits;//7
        }
        public static void SetTCP(string ipaddress, int portNum)
        {
            ModBusTCPIPWrapper.Ipaddress = ipaddress;
            ModBusTCPIPWrapper.PortNum = portNum;
        }
        public static int SetDReg(int Reg, int RegValue)
        {
            DeltaErrCode Result;
            int DReg = (int)DeltaPLC_Reg.D + Reg;

            try
            {
                string tx = String.Concat("00", "06", DReg.ToString("X4"), RegValue.ToString("X4"));
                string rx = Read(tx);

                if (rx == "Port is not Exist")
                    Result = DeltaErrCode.ERR_PORT_WRONG;
                else if (rx == "Port Already in use by another application")
                    Result = DeltaErrCode.ERR_PORT_OCCUPANCY;
                else
                    Result = DeltaErrCode.ERR_SUCCESS;
            }
            catch
            {
                Result = DeltaErrCode.ERR_EXCUTE;
            }

            return (int)Result;
        }

        public static int SetDDReg(int Reg, int RegValue)
        {
            int LowWord = 0, HighWord = 0;
            int DReg = (int)DeltaPLC_Reg.D + Reg;
            string tx, rx;
            DeltaErrCode Result;

            LowWord = RegValue & 0xFFFF;
            HighWord = (RegValue >> 16) & 0xFFFF;

            try
            {

                tx = String.Concat("00", "06", DReg.ToString("X4"), LowWord.ToString("X4"));
                rx = Read(tx);

                if (rx == "Port is not Exist")
                    Result = DeltaErrCode.ERR_PORT_WRONG;
                else if (rx == "Port Already in use by another application")
                    Result = DeltaErrCode.ERR_PORT_OCCUPANCY;
                else
                    Result = DeltaErrCode.ERR_SUCCESS;
            }
            catch
            {
                Result = DeltaErrCode.ERR_EXCUTE;
            }

            if (Result != DeltaErrCode.ERR_SUCCESS)
                return (int)Result;

            try
            {
                LowWord = RegValue & 0xFFFF;
                HighWord = (RegValue >> 16) & 0xFFFF;

                tx = String.Concat("00", "06", (DReg + 1).ToString("X4"), HighWord.ToString("X4"));
                rx = Read(tx);

                if (rx == "Port is not Exist")
                    Result = DeltaErrCode.ERR_PORT_WRONG;
                else if (rx == "Port Already in use by another application")
                    Result = DeltaErrCode.ERR_PORT_OCCUPANCY;
                else
                    Result = DeltaErrCode.ERR_SUCCESS;
            }
            catch
            {
                Result = DeltaErrCode.ERR_EXCUTE;
            }

            return (int)Result;
        }

        public static int ReadDReg(int Reg, out double RegValue)
        {
            DeltaErrCode Result = DeltaErrCode.ERR_SUCCESS;
            string tx = "", rx = "";
            Reg += (int)DeltaPLC_Reg.D;


            try
            {
                tx = String.Concat("00", "03", Reg.ToString("X4"), "0001");
                rx = Read(tx);

                if (rx == "Port is not Exist")
                    Result = DeltaErrCode.ERR_PORT_WRONG;
                else if (rx == "Port Already in use by another application")
                    Result = DeltaErrCode.ERR_PORT_OCCUPANCY;
                else
                    Result = DeltaErrCode.ERR_SUCCESS;
            }
            catch
            {
                Result = DeltaErrCode.ERR_EXCUTE;
            }
            finally
            {
                if (Result == DeltaErrCode.ERR_SUCCESS)
                {
                    if (rx != "")
                        RegValue = Modbus.ToDec(rx.Substring(7, 4), 0, 4);
                    else RegValue = 0;
                }
                else
                    RegValue = 0;
            }

            return (int)Result;

        }


        public static int ReadDDReg(int Reg, out double RegValue)
        {
            DeltaErrCode Result = DeltaErrCode.ERR_SUCCESS;
            string tx = "", rx = "";
            double RegData_Tmp = 0;
            ushort LowWord = 0, HighWord = 0;

            Reg += (int)DeltaPLC_Reg.D;

            //Low
            try
            {
                tx = String.Concat("00", "03", Reg.ToString("X4"), "0001");
                rx = Read(tx);

                if (rx == "Port is not Exist")
                    Result = DeltaErrCode.ERR_PORT_WRONG;
                else if (rx == "Port Already in use by another application")
                    Result = DeltaErrCode.ERR_PORT_OCCUPANCY;
                else
                    Result = DeltaErrCode.ERR_SUCCESS;
            }
            catch
            {
                Result = DeltaErrCode.ERR_EXCUTE;
            }
            finally
            {
                if (Result == DeltaErrCode.ERR_SUCCESS)
                {
                    RegData_Tmp = Modbus.ToDec(rx.Substring(7, 4), 0, 4);
                    LowWord = (ushort)RegData_Tmp;
                }
            }

            if (Result != DeltaErrCode.ERR_SUCCESS)
            {
                RegValue = 0;
                return (int)Result;
            }

            //High
            try
            {
                tx = String.Concat("00", "03", (Reg + 1).ToString("X4"), "0001");
                rx = Read(tx);

                if (rx == "Port is not Exist")
                    Result = DeltaErrCode.ERR_PORT_WRONG;
                else if (rx == "Port Already in use by another application")
                    Result = DeltaErrCode.ERR_PORT_OCCUPANCY;
                else
                    Result = DeltaErrCode.ERR_SUCCESS;
            }
            catch
            {
                Result = DeltaErrCode.ERR_EXCUTE;
            }
            finally
            {
                if (Result == DeltaErrCode.ERR_SUCCESS)
                {
                    RegData_Tmp = Modbus.ToDec(rx.Substring(7, 4), 0, 4);
                    HighWord = (ushort)RegData_Tmp;
                    RegValue = (int)(LowWord + (HighWord << 16));
                }
                else
                {
                    RegValue = 0;
                }
                
            }

            return (int)Result;
        }

        public static int SetMReg(int Reg, bool RegState)
        {
            DeltaErrCode Result = DeltaErrCode.ERR_SUCCESS;
            string tx = "", rx = "";
            string RegStateValue;

            Reg += (int)DeltaPLC_Reg.M;

            if (RegState)
                RegStateValue = "FF00";
            else
                RegStateValue = "0000";
            try
            {
                tx = String.Concat("00", "05", Reg.ToString("X4"), RegStateValue);
                rx = Read(tx);
                if (rx == "Port is not Exist")
                    Result = DeltaErrCode.ERR_PORT_WRONG;
                else if (rx == "Port Already in use by another application")
                    Result = DeltaErrCode.ERR_PORT_OCCUPANCY;
                else
                    Result = DeltaErrCode.ERR_SUCCESS;
            }
            catch
            {
                Result = DeltaErrCode.ERR_EXCUTE;
            }

            if (Result == DeltaErrCode.ERR_SUCCESS)
            {
                string sCheck = String.Concat(":", tx, Modbus.CheckSum(tx), "\r");
                while (!(rx.Equals(sCheck)))
                {
                    rx = Read(tx);
                }
            }

            return (int)Result;
        }
        public static int ReadMReg(int Reg, out bool RegState)
        {
            DeltaErrCode Result = DeltaErrCode.ERR_SUCCESS;
            string tx = "", rx = "";
            Reg += (int)DeltaPLC_Reg.M;

            try
            {
                tx = String.Concat("00", "01", Reg.ToString("X4"), "0001");
                rx = Read(tx);

                if (rx == "Port is not Exist")
                    Result = DeltaErrCode.ERR_PORT_WRONG;
                else if (rx == "Port Already in use by another application")
                    Result = DeltaErrCode.ERR_PORT_OCCUPANCY;
                else
                    Result = DeltaErrCode.ERR_SUCCESS;
            }
            catch
            {
                Result = DeltaErrCode.ERR_EXCUTE;
            }
            finally
            {
                if (Result == DeltaErrCode.ERR_SUCCESS)
                {
                    if (rx.Length > 8)
                    {
                        int nCheck = Convert.ToInt32(rx.Substring(8, 1),16);
                        if ((nCheck % 2) != 0)
                        {
                            RegState = true;
                        }
                        else
                        {
                            RegState = false;
                        }
                    }
                    else
                        RegState = false;
                }
                else
                    RegState = false;
            }

            return (int)Result;
        }

        public static string ReturnCodeDef(DeltaErrCode CodeNum)
        {
            string CodeInfo = "";
            switch (CodeNum)
            {
                case DeltaErrCode.ERR_SUCCESS:
                    CodeInfo = "執行命令成功";
                    break;
                case DeltaErrCode.ERR_CMD_CODE_INVALID:
                    CodeInfo = "命令碼錯誤";
                    break;
                case DeltaErrCode.ERR_DEVICE_ADDR_INVALID:
                    CodeInfo = "Device位置錯誤";
                    break;
                case DeltaErrCode.ERR_REQUEST_DATA_OVERRANGE:
                    CodeInfo = "要求資料超過範圍";
                    break;
                case DeltaErrCode.ERR_WRITE_DATA_OVERRANGE:
                    CodeInfo = "寫入資料無效或是超過範圍";
                    break;
                case DeltaErrCode.ERR_EXCUTE:
                    CodeInfo = "執行命令失敗";
                    break;
                case DeltaErrCode.ERR_PORT_OCCUPANCY:
                    CodeInfo = "端口\"" + Modbus.COMPort + "\"被占用";
                    break;
                case DeltaErrCode.ERR_PORT_WRONG:
                    CodeInfo = "端口\"" + Modbus.COMPort + "\"不存在";
                    break;
            }


            return CodeInfo;
        }


        public static string Read(string tx)
        {
            string r = "";
            if (IsTCP)
            {
             r=   ModBusTcp.Read(tx);
            }
            else
            {
                r = Modbus.Read(tx);
            }
            return r;
        }
    }

    enum DeltaErrCode
    {
        ERR_SUCCESS = 0,
        ERR_CMD_CODE_INVALID = 1,
        ERR_DEVICE_ADDR_INVALID = 2,
        ERR_REQUEST_DATA_OVERRANGE = 3,
        ERR_WRITE_DATA_OVERRANGE = 4,
        ERR_EXCUTE =5,
        ERR_PORT_OCCUPANCY = 6,
        ERR_PORT_WRONG = 7,


    }

    enum DeltaPLC_Reg
    {
        S = 0,
        X = 0x400,
        Y = 0x500,
        T = 0x600,
        M = 0x800,
        C = 0xE00,
        D = 0x1000,
        D4096 = 0x9000,
        M1563 = 0xB000
    }

}
